#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "hfp_app.h"
#include "led.h"
#include "buzzer.h"
#include "my_adc.h"
#include "alert_ctrl.h"

static xQueueHandle task_queue = NULL;
static xTaskHandle task_handle = NULL;

// 常驻任务
static void task_handler(void *arg)
{
    // 颜色表
    const unsigned long color_table[] = {0x000000FF, 0x0000FF00, 0x00FF0000, 0x0000FFFF};
    unsigned char tmp_r, tmp_g, tmp_b;
    unsigned int count = 0;
    bool is_connect = false;
    // 亮度等级
    float luminance;
    int adc_value;
    ALERT_ENENT_TYPE event;
    while (1) {
        // 读取消息队列 100ms超时时间
        if (pdTRUE == xQueueReceive(task_queue, &event, 100 / portTICK_PERIOD_MS)) {
            switch(event)
            {
                case ALERT_ENENT_CALL_IN:
                {
                    int i = 4;
                    // 读取光强
                    adc_value = my_adc_get_value();

                    // 调整亮度适合人眼
                    if(adc_value <= 500) luminance = 2.0/255;
                    else if(adc_value <= 1000) luminance = 10.0/255;
                    else if(adc_value <= 1500) luminance = 40.0/255;
                    else if(adc_value <= 2000) luminance = 60.0/255;
                    else if(adc_value <= 2500) luminance = 100.0/255;
                    else luminance = 1;

                    while(i){
                        i--;
                        // 根据光强度调整亮度
                        tmp_r = (unsigned char)((color_table[i] & 0xFF) * luminance);
                        tmp_g = (unsigned char)((color_table[i]>>8 & 0xFF) * luminance);
                        tmp_b = (unsigned char)((color_table[i]>>16 & 0xFF) * luminance);
                        printf("rgb: %d %d %d\n", tmp_r,tmp_g,tmp_b );
                        led_set_color(RGB(tmp_r,tmp_g,tmp_b));
                        vTaskDelay(300 / portTICK_PERIOD_MS);
                    }
                    led_set_color(0x00000000);
                    // 蜂鸣器响4声
                    i = 4;
                    while(i){
                        buzzer_start(BUZZER_NUM_1|BUZZER_NUM_2);
                        vTaskDelay(150 / portTICK_PERIOD_MS);
                        buzzer_stop(BUZZER_NUM_1|BUZZER_NUM_2);
                        vTaskDelay(150 / portTICK_PERIOD_MS);
                        i--;
                    }
                }
                break;
                case ALERT_ENENT_BT_CONNWCT:      // 蓝牙连接
                    is_connect = true;
                    // 蜂鸣器响一声
                    buzzer_start(BUZZER_NUM_1);
                    vTaskDelay(1000 / portTICK_PERIOD_MS);
                    buzzer_stop(BUZZER_NUM_1);
                break;
                case ALERT_ENENT_BT_DISCONNWCT:    // 蓝牙断开
                    is_connect = false;
                    // 蜂鸣器响两声
                    buzzer_start(BUZZER_NUM_1);
                    vTaskDelay(300 / portTICK_PERIOD_MS);
                    buzzer_stop(BUZZER_NUM_1);
                    vTaskDelay(300 / portTICK_PERIOD_MS);
                    buzzer_start(BUZZER_NUM_1);
                    vTaskDelay(300 / portTICK_PERIOD_MS);
                    buzzer_stop(BUZZER_NUM_1);
                break;
            }
        }
        else    // 状态提示灯
        {
            if(!led_get_color())
            {
                if(is_connect) 
                {
                    if(!(count%100))
                        led_set_color(RGB(0,0,1));
                }
                else
                {
                    led_set_color(RGB(1,0,0));
                }
            }
            else
            {
                led_set_color(0);
            }
            count++;
        }
    }
}

// 初始化
void alert_ctrl_init(void)
{
    // 创建队列用来通信
    task_queue = xQueueCreate(10, sizeof(ALERT_ENENT_TYPE));
    // 创建一个常驻任务
    xTaskCreate(task_handler, "alert_ctrl_task", 2048, NULL, configMAX_PRIORITIES - 3, &task_handle);
}

// 发送通知事件
bool alert_ctrl_send_event(ALERT_ENENT_TYPE event)
{
    if (xQueueSend(task_queue, &event, 10 / portTICK_RATE_MS) != pdTRUE) {
        ESP_LOGE(BT_HF_TAG, "%s xQueue send failed", __func__);
        return false;
    }
    ESP_LOGI(BT_HF_TAG, "%s xQueue send complete", __func__);
    return true;
}
